void __init smp_prepare_cpus(unsigned int max_cpus)
{
- int cpu;
+ int cpu, rc;
struct task_struct *idle;
- if (max_cpus == 0) {
- xen_start_info->n_vcpu = 1;
+ if (max_cpus == 0)
return;
- }
-
- if (max_cpus < xen_start_info->n_vcpu)
- xen_start_info->n_vcpu = max_cpus;
xen_smp_intr_init(0);
- for (cpu = 1; cpu < xen_start_info->n_vcpu; cpu++) {
+ for (cpu = 1; cpu < max_cpus; cpu++) {
+ rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL);
+ if (rc == -ENOENT)
+ break;
+ BUG_ON(rc != 0);
+
cpu_data[cpu] = boot_cpu_data;
cpu_2_logical_apicid[cpu] = cpu;
x86_cpu_to_apicid[cpu] = cpu;
make_page_readonly((void *)cpu_gdt_descr[cpu].address);
cpu_set(cpu, cpu_possible_map);
+ if (xen_start_info->flags & SIF_INITDOMAIN)
+ cpu_set(cpu, cpu_present_map);
vcpu_prepare(cpu);
}
void __devinit smp_prepare_boot_cpu(void)
{
cpu_possible_map = cpumask_of_cpu(0);
+ cpu_present_map = cpumask_of_cpu(0);
cpu_online_map = cpumask_of_cpu(0);
cpu_data[0] = boot_cpu_data;
cpu_set(0, cpu_core_map[0]);
}
-#ifdef CONFIG_HOTPLUG_CPU
-
-static void handle_vcpu_hotplug_event(
- struct xenbus_watch *watch, const char **vec, unsigned int len)
+static void vcpu_hotplug(unsigned int cpu)
{
- int err, cpu;
+ int err;
char dir[32], state[32];
- char *cpustr;
- const char *node = vec[XS_WATCH_PATH];
- if ((cpustr = strstr(node, "cpu/")) == NULL)
+ if ((cpu >= NR_CPUS) || !cpu_possible(cpu))
return;
- sscanf(cpustr, "cpu/%d", &cpu);
-
sprintf(dir, "cpu/%d", cpu);
err = xenbus_scanf(NULL, dir, "availability", "%s", state);
if (err != 1) {
return;
}
- if (strcmp(state, "online") == 0)
+ if (strcmp(state, "online") == 0) {
+ cpu_set(cpu, cpu_present_map);
(void)cpu_up(cpu);
- else if (strcmp(state, "offline") == 0)
+ } else if (strcmp(state, "offline") == 0) {
+#ifdef CONFIG_HOTPLUG_CPU
(void)cpu_down(cpu);
- else
- printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n",
- state, node);
+#else
+ printk(KERN_INFO "Ignoring CPU%d hotplug request\n", cpu);
+#endif
+ } else {
+ printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
+ state, cpu);
+ }
+}
+
+static void handle_vcpu_hotplug_event(
+ struct xenbus_watch *watch, const char **vec, unsigned int len)
+{
+ int cpu;
+ char *cpustr;
+ const char *node = vec[XS_WATCH_PATH];
+
+ if ((cpustr = strstr(node, "cpu/")) != NULL) {
+ sscanf(cpustr, "cpu/%d", &cpu);
+ vcpu_hotplug(cpu);
+ }
}
static int setup_cpu_watcher(struct notifier_block *notifier,
unsigned long event, void *data)
{
+ int i;
+
static struct xenbus_watch cpu_watch = {
.node = "cpu",
.callback = handle_vcpu_hotplug_event };
(void)register_xenbus_watch(&cpu_watch);
+
+ for_each_cpu(i)
+ vcpu_hotplug(i);
+
+ printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus());
+
return NOTIFY_DONE;
}
subsys_initcall(setup_vcpu_hotplug_event);
+#ifdef CONFIG_HOTPLUG_CPU
+
int __cpu_disable(void)
{
cpumask_t map = cpu_online_map;
#endif
}
-#else /* ... !CONFIG_HOTPLUG_CPU */
+#else /* !CONFIG_HOTPLUG_CPU */
int __cpu_disable(void)
{
const char *cmdline,
unsigned long shared_info_frame,
unsigned long flags,
- unsigned int vcpus,
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
{
const char *cmdline,
unsigned long shared_info_frame,
unsigned long flags,
- unsigned int vcpus,
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
{
start_info->store_evtchn = store_evtchn;
start_info->console_mfn = *console_mfn;
start_info->console_evtchn = console_evtchn;
- start_info->n_vcpu = vcpus;
if ( initrd_len != 0 )
{
start_info->mod_start = vinitrd_start;
const char *ramdisk_name,
const char *cmdline,
unsigned long flags,
- unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn,
unsigned int console_evtchn,
&vstartinfo_start, &vkern_entry,
&vstack_start, ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
- flags, vcpus,
- store_evtchn, store_mfn,
+ flags, store_evtchn, store_mfn,
console_evtchn, console_mfn) < 0 )
{
ERROR("Error constructing guest OS");
const char *ramdisk_name,
const char *cmdline,
unsigned long flags,
- unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn,
unsigned int console_evtchn,
uint32_t dom;
char *image, *ramdisk = NULL, *cmdline = "";
- int flags = 0, vcpus = 1;
+ int flags = 0;
int store_evtchn, console_evtchn;
unsigned long store_mfn = 0;
unsigned long console_mfn = 0;
static char *kwd_list[] = { "dom", "store_evtchn",
"console_evtchn", "image",
/* optional */
- "ramdisk", "cmdline", "flags",
- "vcpus", NULL };
+ "ramdisk", "cmdline", "flags", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list,
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssi", kwd_list,
&dom, &store_evtchn,
&console_evtchn, &image,
/* optional */
- &ramdisk, &cmdline, &flags,
- &vcpus) )
+ &ramdisk, &cmdline, &flags) )
return NULL;
if ( xc_linux_build(xc->xc_handle, dom, image,
- ramdisk, cmdline, flags, vcpus,
+ ramdisk, cmdline, flags,
store_evtchn, &store_mfn,
console_evtchn, &console_mfn) != 0 )
return PyErr_SetFromErrno(xc_error);
store_evtchn = store_evtchn,
console_evtchn = console_evtchn,
cmdline = self.cmdline,
- ramdisk = self.ramdisk,
- vcpus = self.vm.getVCpuCount())
+ ramdisk = self.ramdisk)
if isinstance(ret, dict):
self.set_vminfo(ret)
return 0
si = (start_info_t *)vstartinfo_start;
memset(si, 0, PAGE_SIZE);
si->nr_pages = nr_pages;
- si->n_vcpu = num_online_cpus();
if ( opt_dom0_translate )
{
unsigned long mfn_list; /* VIRTUAL address of page-frame list. */
unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */
unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
- uint32_t n_vcpu;
int8_t cmd_line[MAX_GUEST_CMDLINE];
} start_info_t;